﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace ArticleWeb.Common
{
    public static class CipherHelper
    {
        public enum HashFormat
        {
            MD516,
            MD532,
            RIPEMD160,
            SHA1,
            SHA256,
            SHA384,
            SHA512
        }

        public enum HmacFormat
        {
            HMACMD5,
            HMACRIPEMD160,
            HMACSHA1,
            HMACSHA256,
            HMACSHA384,
            HMACSHA512
        }

        public enum SymmetricFormat
        {
            DES,
            TripleDES,
            RC2,
            Rijndael,
            AES
        }

        public static string CreateRandom()
        {
            return CipherHelper.CreateRandom(8);
        }

        public static string CreateRandom(int len)
        {
            string str = "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789!@#$%^&*";
            return CipherHelper.CreateRandom(str, len);
        }

        public static string CreateRandom(string str, int len)
        {
            bool flag = string.IsNullOrEmpty(str);
            if (flag)
            {
                throw new ArgumentNullException("str");
            }
            bool flag2 = len < 1;
            if (flag2)
            {
                throw new ArgumentOutOfRangeException("len");
            }
            Random random = new Random(Guid.NewGuid().GetHashCode());
            int length = str.Length;
            StringBuilder stringBuilder = new StringBuilder(len);
            for (int i = 0; i < len; i++)
            {
                stringBuilder.Append(str.Substring(random.Next(length), 1));
            }
            return stringBuilder.ToString();
        }

        public static string Hash(string inputString, CipherHelper.HashFormat hashFormat = CipherHelper.HashFormat.SHA1)
        {
            HashAlgorithm hashAlgorithm = CipherHelper.GetHashAlgorithm(hashFormat);
            hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString));
            bool flag = hashFormat == CipherHelper.HashFormat.MD516;
            string result;
            if (flag)
            {
                result = BitConverter.ToString(hashAlgorithm.Hash).Replace("-", "").Substring(8, 16).ToUpper();
            }
            else
            {
                result = BitConverter.ToString(hashAlgorithm.Hash).Replace("-", "").ToUpper();
            }
            return result;
        }

        public static string Hmac(string inputString, string key, CipherHelper.HmacFormat hashFormat = CipherHelper.HmacFormat.HMACSHA1)
        {
            HMAC hmac = CipherHelper.GetHmac(hashFormat, Encoding.ASCII.GetBytes(key));
            hmac.ComputeHash(Encoding.UTF8.GetBytes(inputString));
            return BitConverter.ToString(hmac.Hash).Replace("-", "").ToUpper();
        }

        public static string SymmetricEncrypt(string inputString, CipherHelper.SymmetricFormat symmetricFormat, string key, string iv)
        {
            SymmetricAlgorithm symmetricAlgorithm = CipherHelper.GetSymmetricAlgorithm(symmetricFormat);
            byte[] bytes = Encoding.UTF8.GetBytes(inputString);
            byte[] bytes2 = Encoding.ASCII.GetBytes(key);
            byte[] bytes3 = Encoding.ASCII.GetBytes(iv);
            bool flag = !symmetricAlgorithm.ValidKeySize(bytes2.Length * 8);
            if (flag)
            {
                throw new ArgumentOutOfRangeException("key");
            }
            bool flag2 = symmetricAlgorithm.IV.Length != bytes3.Length;
            if (flag2)
            {
                throw new ArgumentOutOfRangeException("iv");
            }
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, symmetricAlgorithm.CreateEncryptor(bytes2, bytes3), CryptoStreamMode.Write);
            cryptoStream.Write(bytes, 0, bytes.Length);
            cryptoStream.FlushFinalBlock();
            cryptoStream.Close();
            return Convert.ToBase64String(memoryStream.ToArray());
        }

        public static string SymmetricDecrypt(string inputString, CipherHelper.SymmetricFormat symmetricFormat, string key, string iv)
        {
            SymmetricAlgorithm symmetricAlgorithm = CipherHelper.GetSymmetricAlgorithm(symmetricFormat);
            byte[] array = Convert.FromBase64String(inputString);
            byte[] bytes = Encoding.ASCII.GetBytes(key);
            byte[] bytes2 = Encoding.ASCII.GetBytes(iv);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, symmetricAlgorithm.CreateDecryptor(bytes, bytes2), CryptoStreamMode.Write);
            cryptoStream.Write(array, 0, array.Length);
            cryptoStream.FlushFinalBlock();
            cryptoStream.Close();
            return Encoding.UTF8.GetString(memoryStream.ToArray());
        }

        //public static string RsaEncrypt(string message, string publicKey, bool fromXml = true)
        //{
        //    string result;
        //    using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider())
        //    {
        //        if (fromXml)
        //        {
        //            rSACryptoServiceProvider.FromXmlString(publicKey);
        //        }
        //        else
        //        {
        //            RSAExtension.FromX509PublicKey(rSACryptoServiceProvider, Convert.FromBase64String(publicKey));
        //        }
        //        byte[] bytes = Encoding.UTF8.GetBytes(message);
        //        byte[] inArray = rSACryptoServiceProvider.Encrypt(bytes, false);
        //        result = Convert.ToBase64String(inArray);
        //    }
        //    return result;
        //}

        //public static string RsaDecrypt(string message, string privateKey, bool fromXml = true)
        //{
        //    string @string;
        //    using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider())
        //    {
        //        if (fromXml)
        //        {
        //            rSACryptoServiceProvider.FromXmlString(privateKey);
        //        }
        //        else
        //        {
        //            RSAExtension.FromPKCS8PrivateKey(rSACryptoServiceProvider, Convert.FromBase64String(privateKey));
        //        }
        //        byte[] rgb = Convert.FromBase64String(message);
        //        byte[] bytes = rSACryptoServiceProvider.Decrypt(rgb, false);
        //        @string = Encoding.UTF8.GetString(bytes);
        //    }
        //    return @string;
        //}

        //public static string RsaSignature(string message, string privateKey, bool fromXml = true)
        //{
        //    string result;
        //    using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider())
        //    {
        //        if (fromXml)
        //        {
        //            rSACryptoServiceProvider.FromXmlString(privateKey);
        //        }
        //        else
        //        {
        //            RSAExtension.FromPKCS8PrivateKey(rSACryptoServiceProvider, Convert.FromBase64String(privateKey));
        //        }
        //        byte[] bytes = Encoding.UTF8.GetBytes(message);
        //        byte[] inArray = rSACryptoServiceProvider.SignData(bytes, "SHA1");
        //        result = Convert.ToBase64String(inArray);
        //    }
        //    return result;
        //}

        //public static bool RsaVerifySign(string message, string signature, string publicKey, bool fromXml = true)
        //{
        //    bool result;
        //    using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider())
        //    {
        //        if (fromXml)
        //        {
        //            rSACryptoServiceProvider.FromXmlString(publicKey);
        //        }
        //        else
        //        {
        //            RSAExtension.FromX509PublicKey(rSACryptoServiceProvider, Convert.FromBase64String(publicKey));
        //        }
        //        byte[] bytes = Encoding.UTF8.GetBytes(message);
        //        byte[] signature2 = Convert.FromBase64String(signature);
        //        result = rSACryptoServiceProvider.VerifyData(bytes, "SHA1", signature2);
        //    }
        //    return result;
        //}

        public static void CreateKeyFileForAsymmetricAlgorithm(string publicFileName, string privateFileName)
        {
            bool flag = string.IsNullOrEmpty(publicFileName);
            if (flag)
            {
                throw new ArgumentNullException("publicFileName");
            }
            bool flag2 = string.IsNullOrEmpty(privateFileName);
            if (flag2)
            {
                throw new ArgumentNullException("privateFileName");
            }
            using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider())
            {
                File.WriteAllText(publicFileName, rSACryptoServiceProvider.ToXmlString(false));
                File.WriteAllText(privateFileName, rSACryptoServiceProvider.ToXmlString(true));
            }
        }

        public static string GetKeyFromFileForAsymmetricAlgorithm(string fileName)
        {
            bool flag = string.IsNullOrEmpty(fileName);
            if (flag)
            {
                throw new ArgumentNullException("fileName");
            }
            return File.ReadAllText(fileName);
        }

        private static HashAlgorithm GetHashAlgorithm(CipherHelper.HashFormat hashFormat)
        {
            HashAlgorithm result = null;
            switch (hashFormat)
            {
                case CipherHelper.HashFormat.MD516:
                    result = MD5.Create();
                    break;
                case CipherHelper.HashFormat.MD532:
                    result = MD5.Create();
                    break;
                case CipherHelper.HashFormat.RIPEMD160:
                    result = RIPEMD160.Create();
                    break;
                case CipherHelper.HashFormat.SHA1:
                    result = SHA1.Create();
                    break;
                case CipherHelper.HashFormat.SHA256:
                    result = SHA256.Create();
                    break;
                case CipherHelper.HashFormat.SHA384:
                    result = SHA384.Create();
                    break;
                case CipherHelper.HashFormat.SHA512:
                    result = SHA512.Create();
                    break;
            }
            return result;
        }

        private static HMAC GetHmac(CipherHelper.HmacFormat hmacFormat, byte[] key)
        {
            HMAC result = null;
            switch (hmacFormat)
            {
                case CipherHelper.HmacFormat.HMACMD5:
                    result = new HMACMD5(key);
                    break;
                case CipherHelper.HmacFormat.HMACRIPEMD160:
                    result = new HMACRIPEMD160(key);
                    break;
                case CipherHelper.HmacFormat.HMACSHA1:
                    result = new HMACSHA1(key);
                    break;
                case CipherHelper.HmacFormat.HMACSHA256:
                    result = new HMACSHA256(key);
                    break;
                case CipherHelper.HmacFormat.HMACSHA384:
                    result = new HMACSHA384(key);
                    break;
                case CipherHelper.HmacFormat.HMACSHA512:
                    result = new HMACSHA512(key);
                    break;
            }
            return result;
        }

        private static SymmetricAlgorithm GetSymmetricAlgorithm(CipherHelper.SymmetricFormat symmetricFormat)
        {
            SymmetricAlgorithm result = null;
            switch (symmetricFormat)
            {
                case CipherHelper.SymmetricFormat.DES:
                    result = DES.Create();
                    break;
                case CipherHelper.SymmetricFormat.TripleDES:
                    result = TripleDES.Create();
                    break;
                case CipherHelper.SymmetricFormat.RC2:
                    result = RC2.Create();
                    break;
                case CipherHelper.SymmetricFormat.Rijndael:
                    result = Rijndael.Create();
                    break;
                case CipherHelper.SymmetricFormat.AES:
                    result = Aes.Create();
                    break;
            }
            return result;
        }
    }
}